﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Co_location
{
    class General
    {
        public static void OutputLabelCor(Dictionary<int, Dictionary<int, double>> weight, Dictionary<int, Dictionary<int, double>> correlation)
        {
            StreamWriter writer = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\LabelCorrelation.txt");
            foreach (int userA in correlation.Keys)
            {
                foreach (int userB in correlation.Keys)
                {
                    if (userA >= userB || weight[userA][userB] == 0)
                        continue;

                    writer.WriteLine(weight[userA][userB].ToString("0.00000") + " " + correlation[userA][userB].ToString("0.00000"));
                }
            }
            writer.Close();
        }

        public static void OutputFivePercent(Dictionary<int, Dictionary<int, double>> weightTable)
        {
            StreamWriter writer = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\FivePercent.txt");
            List<double> output = getFirstLastFivePercent(weightTable);
            foreach (double d in output)
                writer.Write(d.ToString("0.00000") + " ");
            writer.Close();
        }

        public static List<double> getFirstLastFivePercent(Dictionary<int, Dictionary<int, double>> weightTable)
        {
            List<double> d = new List<double>();
            foreach (int ua in weightTable.Keys)
                foreach (int ub in weightTable.Keys)
                {
                    if (weightTable[ua][ub] == 0)
                        continue;
                    d.Add(weightTable[ua][ub]);
                }
            
            d.Sort();
            List<double> firstFive = new List<double>(), lastFive = new List<double>(), midFive = new List<double>();
            for (int i = 0; i < d.Count / 2; i++)
            {
                firstFive.Add(d[d.Count - 1 - i]);
                midFive.Add(d[d.Count * 1 / 4 + i]);
                lastFive.Add(d[i]);
            }
            return new List<double>() { lastFive.Average(), midFive.Average(), firstFive.Average() };
        }

        public static void OutputAverage(Dictionary<int, Dictionary<int, double>> weight, Dictionary<int, Dictionary<int, double>> correlation)
        {
            Dictionary<int, List<double>> values = new Dictionary<int, List<double>>();
            Dictionary<int, double> valueAverages = new Dictionary<int, double>();
            
            foreach(int ua in correlation.Keys)
                foreach (int ub in correlation.Keys)
                {
                    if (ua >= ub || weight[ua][ub] == 0)
                        continue;
                    int x = (int)Math.Floor(weight[ua][ub] * 20);
                    if (!values.Keys.Contains(x))
                        values.Add(x, new List<double>());
                    values[x].Add(correlation[ua][ub]);
                }

            StreamWriter writer = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\CorrelationAverage.txt");
            foreach (int x in values.Keys)
            {
                valueAverages.Add(x, values[x].Average());
                writer.WriteLine(((double)x / 20).ToString("0.000") + " " + values[x].Average().ToString("0.00000"));
            }
            writer.Close();
        }

        public static void OutputAvgUser(Dictionary<int, Dictionary<int, double>> weightTable,Dictionary<int,int> Dic)
        {
            SortedList<int, double> avgOnUser = new SortedList<int, double>();
            foreach (int user in weightTable.Keys)
            {
                List<double> tmp = new List<double>();
                foreach (int other in weightTable[user].Keys)
                    tmp.Add(weightTable[user][other]);
                avgOnUser.Add(user, tmp.Average());
            }

            StreamWriter writer = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\CorrelationAvgUser.txt");
            foreach (var pair in avgOnUser)
            {
                if (Dic == null)
                    writer.WriteLine(pair.Key + " " + pair.Value.ToString("0.0000"));
                else
                    writer.WriteLine(Dic[pair.Key] + " " + pair.Value.ToString("0.0000"));
            }
            writer.Close();
        }

        public static void OutputAvgEuc(Dictionary<int, Dictionary<int, double>> weightTable, Dictionary<int, int> Dic)
        {
            SortedList<double, int> reverse = new SortedList<double, int>();
            foreach (int user in weightTable.Keys)
            {
                List<double> tmp = new List<double>();
                foreach (int other in weightTable[user].Keys)
                    tmp.Add(weightTable[user][other]);
                reverse.Add(tmp.Average(),user);
            }

            SortedList<int, double> avgOnUser = new SortedList<int, double>();
            double w = 0.7 / (double)reverse.Count, v = 0.7 / (double)reverse.Count;
            foreach (var pair in reverse)
            {
                avgOnUser.Add(pair.Value, 0.9 - v);
                v += w;
            }
            StreamWriter writer = new StreamWriter(System.IO.Directory.GetCurrentDirectory() + "\\CorrelationAvgUserE.txt");
            foreach (var pair in avgOnUser)
            {
                if (Dic == null)
                    writer.WriteLine(pair.Key + " " + pair.Value.ToString("0.0000"));
                else
                    writer.WriteLine(Dic[pair.Key] + " " + pair.Value.ToString("0.0000"));
            }
            writer.Close();
        }
    }
}